#pragma once 
#include "Log.hpp"
#include <jsoncpp/json/json.h>
using namespace MyLogModule;
#define OK 200
#define ERROR_STATUS 400
const string sep = "\r\n";
void Encode(string& out){
    string tmp;
    tmp = to_string(out.size()) + sep + out + sep;
    out.swap(tmp);
}
//1234\r\nXxihao\r\n - 这个才是一个合法的字符串
//1234\r\nnihao
//1234\r
//1234\r\nnihao\r\n12\r\n
//12\r\n123
bool Decode(string& src_str,string* out){
    LOG(LogLevel::DEBUG) << "Raw data size: " << src_str.size();
    for(char c : src_str) {
        printf("%02X ", (unsigned char)c);
    }
    printf("\n");
    //如果没有找到分割符直接退出去
    auto pos = src_str.find(sep);
    if (pos == string::npos) return false;
    LOG(LogLevel::DEBUG) << "查询到的长度字符: " << src_str.substr(0,pos) <<"pos: " << pos;
    int full_length = stoi(src_str.substr(0,pos));
    pos += sep.size();
    auto pos1 = src_str.find(sep,pos);
    if (pos1 == string::npos) return false;
    LOG(LogLevel::DEBUG) << "查询到的内容: " << src_str.substr(pos,pos1-pos) <<"pos1: " << pos1;    
    LOG(LogLevel::DEBUG) << "分割字符长度为: " << sep.size();
    *out = src_str.substr(pos,pos1-pos); //前闭后开区间
    src_str.erase(0,pos1+sep.size()); //把一个完整的报文去除掉
    return true;
}
class Request
{
public:
    Request()
    {}
    Request(int x,int y,char oper)
        :_x(x),_y(y),_oper(oper)
    {}
    void Serialization(string* out){
        Json::Value root;
        root["x"] = _x;
        root["oper"] = _oper;
        root["y"] = _y;
        Json::StreamWriterBuilder wbuilder; //StreamWriterBuilder的工厂
        std::unique_ptr<Json::StreamWriter> writer(wbuilder.newStreamWriter());
        std::stringstream ss;
        writer->write(root,&ss);
        *out = ss.str();
    }
    int X()const {return _x;}
    int Y()const{return _y;}
    char oper()const{return _oper;}
    bool Deserialization(const string& s){
        Json::Reader reader;
        Json::Value root1;
        // 从字符串获取JSON数据
        bool parsingSuccessful = reader.parse(s, root1);
        if (!parsingSuccessful)
        {
            // 解析失败， 输出错误信息
            std::cout << "Failed to parse JSON: " << reader.getFormattedErrorMessages() << std::endl;
            return false;
        }
        _x = root1["x"].asInt(); //注意json中的类型需要进行类型检查
        _y = root1["y"].asInt();
        _oper = root1["oper"].asInt();
        return true;
    }
    void Print(){
        LOG(LogLevel::INFO) << "###############[Request]###############";
        LOG(LogLevel::INFO) << "x: " << _x;
        LOG(LogLevel::INFO) << "y: " << _y;
        LOG(LogLevel::INFO) << "oper: " << _oper;
        LOG(LogLevel::INFO) << "###############[Request]###############";
    }
private:
    int _x;
    int _y;
    char _oper;
};

class Response
{
public:
    Response()
        :_result(0),_status(OK)
        {}
    void SetResult(int result){
        _result = result;
    }
    void SetStatus(int status){
        _status = status;
    }
    Response(const Response&rsp){
        _result = rsp._result;
        _status = rsp._status;
    }
    void Serialization(string* out){
        Json::Value root;
        root["Result"] = _result;
        root["Status"] = _status;
        Json::StreamWriterBuilder wbuilder; //StreamWriterBuilder的工厂
        std::unique_ptr<Json::StreamWriter> writer(wbuilder.newStreamWriter());
        std::stringstream ss;
        writer->write(root,&ss);
        *out = ss.str();
    }
    bool Deserialization(const string& s){
         Json::Reader reader;
        Json::Value root1;
        // 从字符串获取JSON数据
        bool parsingSuccessful = reader.parse(s, root1);
        if (!parsingSuccessful)
        {
            // 解析失败， 输出错误信息
            std::cout << "Failed to parse JSON: " << reader.getFormattedErrorMessages() << std::endl;
            return false;
        }
        _result = root1["Result"].asInt(); //注意json中的类型需要进行类型检查
        _status = root1["Status"].asInt();
        return true;
    }
    void Print(){
        LOG(LogLevel::INFO) << "###############[Response]###############";
        LOG(LogLevel::INFO) << "Result: " << _result;
        LOG(LogLevel::INFO) << "Status: " << _status;
        LOG(LogLevel::INFO) << "###############[Response]###############";
    }
private:
    int _result;
    int _status;
};